package elephant.servers.gameserver.connect;

import elephant.servers.gameserver.codec.GameServerBodyCodec;
import elephant.servers.gameserver.codec.GameServerDecoder;
import elephant.servers.gameserver.codec.GameServerEncoder;
import elephant.servers.gameserver.core.GameRequestDispatch;
import elephant.servers.gameserver.session.GameSessionManager;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * 
 * @author icecooly
 *
 */
public class GameServerConnect {
	//
	private int port = 3001;
	private GameSessionManager sessionManager;
	private GameRequestDispatch requestDispatch;
	private GameServerHandler handler;
	private GameServerBodyCodec bodyCodec;
	private ServerBootstrap serverStrap;
	public NioEventLoopGroup bossGroup;
	public NioEventLoopGroup workerGroup;

	//
	public GameServerConnect(GameSessionManager sessionManager, GameRequestDispatch requestDispatch) {
		this.sessionManager = sessionManager;
		this.requestDispatch = requestDispatch;
	}

	public void init() {
		bossGroup = new NioEventLoopGroup();
		workerGroup = new NioEventLoopGroup();
		handler = new GameServerHandler(sessionManager, requestDispatch);
		if(bodyCodec==null){//use default
			bodyCodec=new GameServerBodyCodec();
		}
		serverStrap = new ServerBootstrap();
		serverStrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
				.option(ChannelOption.TCP_NODELAY, true).option(ChannelOption.SO_BACKLOG, 100)
				.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
				.childHandler(new ChannelInitializer<SocketChannel>() {
					@Override
					public void initChannel(SocketChannel ch) throws Exception {
							ch.pipeline().addLast(
									new GameServerDecoder(bodyCodec), 
									new GameServerEncoder(bodyCodec),
									handler);
						
					}
				});
	}

	public void start() throws Exception {
		serverStrap.bind(port).sync();
	}

	//
	public void stop() {
		bossGroup.shutdownGracefully();
		workerGroup.shutdownGracefully();
	}

	//
	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}

	public GameServerBodyCodec getBodyCodec() {
		return bodyCodec;
	}

	public void setBodyCodec(GameServerBodyCodec bodyCodec) {
		this.bodyCodec = bodyCodec;
	}
	
}
